#ifndef __RARRAY_H__
#define __RARRAY_H__

#include <string.h>

typedef struct _rnode_t  rnode_t;
typedef struct _rarray_t rarray_t;

typedef void (* rarray_free_fn_t)(void *value);
typedef void (* rarray_walk_fn_t)(rarray_t *self, void *data, void *context);

typedef struct _rarray_context_t
{
	int		  size;
	int		  count;
	void	**bucket;
} rarray_context_t;

typedef struct _rarray_t
{
	int					 ref;
	rarray_context_t	*context;
	rarray_free_fn_t	 destructor;
} rarray_t;

void rarray_ref(rarray_t *self);
void rarray_unref(rarray_t *self);
void rarray_create(rarray_t *self, rarray_free_fn_t destructor);

void rarray_clear(rarray_t *self);
void rarray_append(rarray_t *self, void *value);
void rarray_foreach(rarray_t *self, rarray_walk_fn_t fn, void *context);

void rarray_save_context(rarray_t *self, rarray_context_t **context);
void rarray_restore_context(rarray_t *self, rarray_context_t **context);

#define rarray_count(a)				((a).context->count)
#define rarray_item_at(a, i, t)		({ int _i = (i); _i >= 0 && _i < (a).context->count ? (t *)((a).context->bucket[_i]) : NULL; })

#endif /* __RARRAY_H__ */
